import { CookieService } from 'ngx-cookie-service';
import { Injectable } from '@angular/core';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
@Injectable({
  providedIn: 'root'
})
export class MelonLibApiService {
  constructor(private http: HttpClient, private cookieService: CookieService) { }
  transConditions(conditions: EntityConditions): string {
    const items = [];
    from(Object.keys(conditions)).pipe(map(name => `${name}=${conditions[name]}`)).subscribe({
      next: item => items.push(item)
    });
    return items.join('&');
  }

  list<ENTITY>(entities: EntityDatas<ENTITY>, success: (value: MelonLibResponse) => void, fail?: () => void, complete?: () => void): void {
    this.http.get(`${entities.url}?page=${entities.page}&rows=${entities.size}&order=${entities.odrType}&sort=${entities.order}&${this.transConditions(entities.conditions)}`
      , { withCredentials: true }).pipe(map(res => res as MelonLibResponse)).subscribe({
        next: res => {
          if (res.status) {
            success(res);
          } else {
            fail();
          }
        }
        , error: fail
        , complete
      });
  }

  emptyDatas<ENTITY>(url: string): EntityDatas<ENTITY> {
    return {
      conditions: {}
      , page: 1
      , size: 20
      , order: 'id'
      , total: 0
      , url
      , odrType: 'ASC'
    };
  }

}

export class MelonLibApiUtils {
  defaultSuccess(entityDatas: EntityDatas<any>, response: MelonLibResponse): (res) => void {
    return res => {
      entityDatas.total = response.total;
      entityDatas.rows = response.rows;
      entityDatas.status = EntityDatasStatus.SUCCESS;
    };
  }
}

export interface MelonLibResponse {
  status: boolean | number;
  rows?: any;
  total?: number;
  [prop: string]: any;
}

export interface HttpRequest {
  readonly url: string;
  method?: HttpRequestMethod;
  auth?: boolean;
  body?: any;
  header?: any;
}

export interface HttpResponse {
  success: <T>(value: T) => void;
  error: () => void;
  finished: () => void;
}

export enum HttpRequestMethod {
  GET, POST, PUT, PATCH, DELETE
}

export interface EntityDatas<ENTITY> {
  url?: string;
  total?: number;
  page?: number;
  size?: number;
  rows?: Array<ENTITY>;
  order?: string;
  conditions?: EntityConditions;
  status?: EntityDatasStatus;
  message?: string;
  odrType?: 'ASC' | 'DESC';
}

export enum EntityDatasStatus {
  SUCCESS, ERROR, NOT_FOUND, ABORT
}

export interface EntityConditions {
  [index: string]: any;
}
export interface EntityComponent {
  checkAll(checked: boolean): void;
  changePage(page: number): void;
  changeSize(size: number): void;
  search(): void;
  sort(name: string, type: 'ASC' | 'DESC'): void;
  editor(entity: any): void;
  remove(entity: any): void;
  removes(entity: any): void;
}
export interface EntityService<ENTITY> {
  searchObs(): Observable<EntityDatas<ENTITY>>;
  index(params: any, success: (res: any) => void): void;
  search(): void;
  setConditions(conditions: EntityConditions): void;
  setPage(page: number): void;
  setSize(size: number): void;
  setOrder(name: string, type: 'ASC' | 'DESC'): void;
  save(entity: ENTITY, success: (res: any) => void, error: () => void): void;
  remove(entity: ENTITY, success: (res: any) => void, error: () => void): void;
  removes(entities: any, success: (res: any) => void, error: () => void): void;
}

export interface CacheApiData<T> {
  name: string;
  store?: 'SESSION' | 'LOCAL' | 'PAGE';
  apiName?: string;
  body?: T;
}
